package lifecycle

import (
	"errors"
	"fmt"
	"log"
	"net"

	"gitee.com/chuanjinge/go-container/container/info"
	"gitee.com/chuanjinge/go-container/container/overlay2"
	"gitee.com/chuanjinge/go-container/container/vethbr"
	"github.com/vishvananda/netlink"
)

// 删除容器
// @param string containerId 容器ID
// @param bool force 是否强制删除
func RemoveContainer(containerId string, force bool) error {
	cInfo, err := info.GetContainerInfoByContainerId(containerId)
	if err != nil {
		return err
	}

	// 检查容器状态，运行状态下，如果指定了force=true则停止，否则报错
	if cInfo.State.Running {
		if !force {
			return errors.New("容器正在运行，无法删除")
		}
		if err := StopContainer(containerId); err != nil {
			return err
		}
	}

	var volumeList []string
	for _, mp := range cInfo.MountPoints {
		volumeList = append(volumeList, fmt.Sprintf("%s:%s", mp.Source, mp.Destination))
	}

	// 1.卸载那些从宿主机挂在过来的卷
	// 2.卸载基于overlay2挂载的根目录卷
	// 3.删除所有目录
	ufs := overlay2.NewUfsDir(containerId)
	if ufs != nil {
		// 先把共享目录卸载掉，要不然overlay应该就卸载不掉了
		ufs.ParseSharedVolume(volumeList)
		if err := ufs.UnmountSharedVolume(); err != nil {
			log.Println(err.Error())
		}
		if err := ufs.Disapper(); err != nil {
			log.Println(err.Error())
		}
	}

	// 4. 删除容器信息文件
	info.RemoveConfigLog(containerId)
	info.RemoveRunLog(containerId)
	// 5. 删除容器目录
	info.RemoveContainerDir(containerId)
	// 6. 网络相关 - 把该动作放到stop之中
	// RemoveContainerNetwork(containerId)

	return nil
}

// 删除容器的网络--该动作在容器的关闭的时候使用
// 1. 虚拟以太对
// 2. 容器内的路由规则
// 3.
func RemoveContainerNetwork(containerId string) error {
	// 1. 删除DNAT的PREROUTING和OUTPUT链上针对当前ip:port的规则
	cInfo, err := info.GetContainerInfoByContainerId(containerId)
	if err != nil {
		return err
	}
	for networkName, network := range cInfo.NetworkSettings.Networks {
		for containerPort, hostPort := range cInfo.NetworkSettings.Ports {
			log.Printf("要删除的容器ip: %s\n", network.IPAddress)
			fmt.Printf("要删除的容器ip: %s\n", network.IPAddress)
			containerIp := net.ParseIP(network.IPAddress)
			if err := vethbr.DeleteIPTablesDNATPrerouting(networkName, hostPort, containerIp, containerPort); err != nil {
				log.Printf("[error]删除 DNAT-PREROUTING 出错:info:%s,%d,%s,%d:err:%v\n", networkName, hostPort, containerIp.String(), containerPort, err)
			}
			if err := vethbr.DeleteIPTablesDNATOutput(hostPort, containerIp, containerPort); err != nil {
				log.Printf("[error]删除 DNAT-OUTPUT 出错:info:%d,%s,%d:err:%v\n", hostPort, containerIp.String(), containerPort, err)
			}
		}
	}

	// 2. 将奇数端从网桥上解绑（centos8下会在删除虚拟接口的时候自动解绑，不实现了）
	// 3. 删除虚拟以太对
	linkPeerName := fmt.Sprintf("d1-%s", containerId)
	link, err := netlink.LinkByName(linkPeerName)
	if err != nil {
		log.Println("找不到虚拟网络接口:", linkPeerName)
	} else {
		if err := netlink.LinkDel(link); err != nil {
			log.Println("删除虚拟网络接口失败", linkPeerName)
		}
	}

	return nil
}
